package com.itcast.springboot.waste_recovery.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itcast.springboot.request.RegisterReq;
import com.itcast.springboot.response.StaffMineRes;
import com.itcast.springboot.utils.ImageUtil;
import com.itcast.springboot.utils.QiNiuYunUtil;
import com.itcast.springboot.utils.SendMail;
import com.itcast.springboot.waste_recovery.common.CommonResult;
import com.itcast.springboot.waste_recovery.common.OrderStatus;
import com.itcast.springboot.waste_recovery.domain.Order;
import com.itcast.springboot.waste_recovery.domain.RolePermission;
import com.itcast.springboot.waste_recovery.domain.User;
import com.itcast.springboot.waste_recovery.domain.UserRole;
import com.itcast.springboot.waste_recovery.mapper.*;
import com.itcast.springboot.waste_recovery.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 小破烂
 * @since 2020-08-17
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Resource(name = "sendMail")
    private SendMail sendMail;

    @Resource
    private OrderMapper orderMapper;

    @Resource(name = "qiNiuYunUtil")
    QiNiuYunUtil qiNiuYunUtil;

    @Resource(name = "imageUtil")
    ImageUtil imageUtil;

    @Override
    public Integer register(RegisterReq register, Integer roleId) {

        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //是否邮箱或手机号已经被注册
        wrapper.eq("user_phone", register.getUserPhone())
                .or()
                .eq("user_email", register.getUserEmail());
        Integer count = userMapper.selectCount(wrapper);
        if (count > 0) {
            //被注册过就返回失败
            return -1;
        }

        User user = new User();
        user.setUserName(register.getUserName());

        //对密码使用Md5加密
        user.setUserPassword(
                new Md5Hash(register.getUserPassword(), register.getUserPhone(), 3)
                        .toString());
        //用户编码使用16位字符编码
        user.setUserCode(RandomUtil.randomString(16));
        user.setUserPhone(register.getUserPhone());
        user.setUserEmail(register.getUserEmail());
        user.setUserSex(register.getUserSex());
        //设置默认头像
        if(user.getUserSex() == true) {
            user.setUserUrl("http://cen.roadvast.top/user/male.png");
        }else {
            user.setUserUrl("http://cen.roadvast.top/user/male.png");
        }
        int result = userMapper.insert(user);
        if (result > 0){
            UserRole userRole = new UserRole();
            userRole.setUserRoleUserid(user.getId());
            userRole.setUserRoleRoleid(roleId);
            result = userRoleMapper.insert(userRole);
        }
        return result;
    }

    @Override
    public Map<String, Object> login(String account, String password) {
        try {
            /**
             * 对密码进行加密：
             *      shiro使用md5进行加密
             *      Md5Hash：
             *          参数一：加密的内容
             *              111111      --Md5加密后--      abcd
             *          参数二：盐（加密的混淆字符串）（一般使用用户登录的用户名）
             *              111111+混淆字符串
             *          参数三：加密次数
             */
            //用户输入的密码
            String inputPwd = password;
            String userPhone = this.findByPhoneOrEmail(account).getUserPhone();
            password = new Md5Hash(password, userPhone, 3).toString();
            log.info("--->enter password： " + password);
            //构造登录令牌
            UsernamePasswordToken token = new UsernamePasswordToken(userPhone, password);
            //获取subject
            Subject subject = SecurityUtils.getSubject();

            //获取session
            String sessionId = (String) subject.getSession().getId();
            log.info("--->token = " + sessionId);

            //调用subject进行登录
            subject.login(token);
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("user_phone", account)
                    .or()
                    .eq("user_email", account);
            User user = userMapper.selectOne(wrapper);
            user.setUserPassword(inputPwd);
            Map<String, Object> map = new HashMap<>();
            map.put("user", user);
            map.put("sessionId", sessionId);

            return map;
        }catch (Exception e){
            return null;
        }
    }

    @Override
    public Map<String, Object> getUserMine(Integer id) {
        User user = userMapper.selectById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("userId", user.getId());
        map.put("userName", user.getUserName());
        map.put("user_isreal", user.getUserIsreal());
        map.put("user_money", user.getUserMoney());
        return map;
    }

    @Override
    public User getUserById(Integer id) {
        User user = userMapper.selectById(id);
        return user;
    }

    @Override
    public User findByPhoneOrEmail(String account) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_phone", account)
        .or()
        .eq("user_email", account)
        ;
        User user = userMapper.selectOne(wrapper);
        return user;
    }

    @Override
    public Map<String, Object> getRolesAndPermissionByUserId(Integer userId) {
        Map<String, Object> map = new HashMap<>();
        Set<String> roleNames = new HashSet<>();
        Set<String> permTypes = new HashSet<>();

        //通过用户id获取对应的角色
        QueryWrapper<UserRole> userRoleWrapper = new QueryWrapper<>();
        userRoleWrapper.eq("user_role_userid", userId);
        List<UserRole> userRoles = userRoleMapper.selectList(userRoleWrapper);
        //通过角色获取对应的权限
        for (UserRole userRole : userRoles) {
            roleNames.add(roleMapper.selectById(userRole.getUserRoleRoleid()).getRoleName());
            QueryWrapper<RolePermission> rolePermissionWrapper = new QueryWrapper<>();
            rolePermissionWrapper.eq("role_permission_roleid", userRole.getUserRoleRoleid());
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionWrapper);
            for (RolePermission rolePermission : rolePermissions) {
                permTypes.add(permissionMapper.selectById(rolePermission.getRolePermissionPermissionid()).getPermissionType());
            }
        }
        map.put("roleNames", roleNames);
        map.put("permTypes", permTypes);

        return map;
    }

    @Override
    public Map<String, Object> getPersonalInformation(Integer id) {
        User user = userMapper.selectById(id);
        //封装个人信息
        Map<String, Object> perInfo = new HashMap<>();
        perInfo.put("userUrl", user.getUserUrl());
        perInfo.put("userName", user.getUserName());
        perInfo.put("userEmail", user.getUserEmail());
        return perInfo;
    }

    @Override
    public Integer updateUsername(Integer id, String username, String userEmail) {
        User user = userMapper.selectById(id);
        if (username != null && userEmail == null){
            //改名字
            user.setUserName(username);
        }else if (username == null && userEmail != null){
            //改邮箱
            user.setUserEmail(userEmail);
        }else {
            //其他情况直接返回错误信息
            return -1;
        }
        return userMapper.updateById(user);
    }

    @Override
    public Boolean bindEmail(String userEmail, String subject, String text) {
        Boolean result = false;
        //判断是否已经被绑定
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //SELECT COUNT( 1 ) FROM user WHERE (user_email = ?) limit 1 ;
        wrapper.eq("user_email", userEmail).last("limit 1");
        Integer count = userMapper.selectCount(wrapper);
        if (count > 0 ){
            result = false;
        }else {
            result = sendMail.sendHtmlMail(userEmail, subject, text);
        }
        return result;
    }

    @Override
    public Integer realNameAuth(Integer userId, String userRealName, String userNum) {
        Integer result = -1;
        User user = userMapper.selectById(userId);
        String regex = "\\d{15}(\\d{2}[0-9xX])?";
        if (user.getUserIsreal() == true) {
            return 0;
        }
        if (userNum.matches(regex)){
            user.setId(userId);
            user.setUserRealName(userRealName);
            user.setUserNum(userNum);
            user.setUserIsreal(true);
            result = userMapper.updateById(user);
        } else{
            log.info("身份证号格式错误");
        }

        return result;
    }

    @Override
    public StaffMineRes getStaffMine(Integer userId) {
        StaffMineRes staffMine = new StaffMineRes();
        User user = userMapper.selectById(userId);
        staffMine.setUserId(user.getId());
        staffMine.setUserName(user.getUserName());
        staffMine.setUserUrl(user.getUserUrl());
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        //正在进行中的订单的数量
        wrapper.eq("order_staff_id", userId)
                .eq("order_status", OrderStatus.ORDER_TAKE.statusCode());
        Integer underWayAmount = orderMapper.selectCount(wrapper);

        //累计已完成的订单的数量
        wrapper = new QueryWrapper<>();
        wrapper.eq("order_staff_id", userId)
                .eq("order_status", OrderStatus.ORDER_SUCCESS.statusCode());
        Integer cumCompleAmount = orderMapper.selectCount(wrapper);

        staffMine.setUnderWayAmount(underWayAmount);
        staffMine.setCumCompleAmount(cumCompleAmount);

        return staffMine;
    }

    @Override
    public String updateStaffUrl(Integer userId, MultipartFile img) {
        String result = "-1";
        User user = userMapper.selectById(userId);
        String userUrl = user.getUserUrl();
        //删除原先的图片
        if (userUrl != null){
            Integer deleteImg = qiNiuYunUtil.deleteImg(userUrl);
        }
        //上传新的图片
        String imgPath = img.getOriginalFilename();
        String imgName = imageUtil.createNewImgName(imgPath);

        System.out.println(imgName);
        try {
            byte[] bytes = img.getBytes();
            result = qiNiuYunUtil.put64image(bytes, imgName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!result.equals("-1")) {
            //更新到数据库
            user.setUserUrl(result);
            Integer.toString(userMapper.updateById(user));
        }

        return result;
    }


}
